package com.ryder.petmatediarybackend.common.util;

import com.google.gson.Gson;
import com.ryder.petmatediarybackend.module.log.entity.SysTaskLog;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 描述: 定时任务日志工具类
 *
 * @author Ryder
 * @version 1.0
 * @since 1.0
 * 更新日期: 2025/10/28
 */
@Slf4j
public class TaskLogUtil {

    private static final Gson gson = new Gson();

    /**
     * 创建任务日志构建器
     *
     * @param taskName 任务名称
     * @return TaskLogBuilder
     */
    public static TaskLogBuilder start(String taskName) {
        return new TaskLogBuilder(taskName);
    }

    /**
     * 任务日志构建器（支持链式调用）
     */
    public static class TaskLogBuilder {
        private final SysTaskLog taskLog;
        private final LocalDateTime startTime;

        public TaskLogBuilder(String taskName) {
            this.taskLog = new SysTaskLog();
            this.startTime = LocalDateTime.now();
            this.taskLog.setTaskName(taskName);
            this.taskLog.setTaskType("SCHEDULED");
            this.taskLog.setStartTime(startTime);
            this.taskLog.setTotalCount(0);
            this.taskLog.setSuccessCount(0);
            this.taskLog.setFailCount(0);
        }

        /**
         * 设置任务类型
         */
        public TaskLogBuilder taskType(String taskType) {
            this.taskLog.setTaskType(taskType);
            return this;
        }

        /**
         * 设置总处理数量
         */
        public TaskLogBuilder totalCount(int count) {
            this.taskLog.setTotalCount(count);
            return this;
        }

        /**
         * 设置成功数量
         */
        public TaskLogBuilder successCount(int count) {
            this.taskLog.setSuccessCount(count);
            return this;
        }

        /**
         * 设置失败数量
         */
        public TaskLogBuilder failCount(int count) {
            this.taskLog.setFailCount(count);
            return this;
        }

        /**
         * 增加成功数量
         */
        public TaskLogBuilder incrementSuccess() {
            this.taskLog.setSuccessCount(this.taskLog.getSuccessCount() + 1);
            return this;
        }

        /**
         * 增加失败数量
         */
        public TaskLogBuilder incrementFail() {
            this.taskLog.setFailCount(this.taskLog.getFailCount() + 1);
            return this;
        }

        /**
         * 设置黑名单 ID 列表
         */
        public TaskLogBuilder blacklistIds(List<Long> ids) {
            if (ids != null && !ids.isEmpty()) {
                this.taskLog.setBlacklistIds(gson.toJson(ids));
            }
            return this;
        }

        /**
         * 设置错误信息
         */
        public TaskLogBuilder error(String errorMessage) {
            this.taskLog.setErrorMessage(errorMessage);
            return this;
        }

        /**
         * 设置错误信息（从异常）
         */
        public TaskLogBuilder error(Exception e) {
            this.taskLog.setErrorMessage(e.getMessage());
            return this;
        }

        /**
         * 设置备注
         */
        public TaskLogBuilder remark(String remark) {
            this.taskLog.setRemark(remark);
            return this;
        }

        /**
         * 完成任务并构建日志对象
         *
         * @return SysTaskLog
         */
        public SysTaskLog finish() {
            LocalDateTime endTime = LocalDateTime.now();
            this.taskLog.setEndTime(endTime);
            
            // 计算执行耗时（毫秒）
            long duration = Duration.between(startTime, endTime).toMillis();
            this.taskLog.setDuration((int) duration);
            
            // 根据成功/失败数量判断执行状态
            int failCount = this.taskLog.getFailCount();
            int successCount = this.taskLog.getSuccessCount();
            
            if (failCount == 0 && successCount > 0) {
                this.taskLog.setExecuteStatus(1);  // 全部成功
            } else if (failCount > 0 && successCount > 0) {
                this.taskLog.setExecuteStatus(2);  // 部分成功
            } else if (failCount > 0 && successCount == 0) {
                this.taskLog.setExecuteStatus(3);  // 全部失败
            } else {
                this.taskLog.setExecuteStatus(1);  // 无数据处理，视为成功
            }
            
            // 打印日志
            log.info("任务执行完成 | 任务名称: {} | 状态: {} | 总数: {} | 成功: {} | 失败: {} | 耗时: {}ms",
                    this.taskLog.getTaskName(),
                    getStatusText(this.taskLog.getExecuteStatus()),
                    this.taskLog.getTotalCount(),
                    this.taskLog.getSuccessCount(),
                    this.taskLog.getFailCount(),
                    this.taskLog.getDuration());
            
            return this.taskLog;
        }

        /**
         * 标记为失败并完成
         */
        public SysTaskLog fail(String errorMessage) {
            this.taskLog.setExecuteStatus(3);
            this.taskLog.setErrorMessage(errorMessage);
            return finish();
        }

        /**
         * 标记为失败并完成（从异常）
         */
        public SysTaskLog fail(Exception e) {
            this.taskLog.setExecuteStatus(3);
            this.taskLog.setErrorMessage(e.getMessage());
            log.error("任务执行失败 | 任务名称: {} | 错误: {}", this.taskLog.getTaskName(), e.getMessage(), e);
            return finish();
        }

        /**
         * 获取状态文本
         */
        private String getStatusText(Integer status) {
            if (status == null) return "未知";
            return switch (status) {
                case 1 -> "成功";
                case 2 -> "部分成功";
                case 3 -> "失败";
                default -> "未知";
            };
        }
    }

    /**
     * 解析黑名单 ID 列表（从 JSON）
     */
    public static List<Long> parseBlacklistIds(String blacklistIdsJson) {
        if (blacklistIdsJson == null || blacklistIdsJson.isEmpty()) {
            return List.of();
        }
        try {
            return gson.fromJson(blacklistIdsJson, List.class);
        } catch (Exception e) {
            log.error("解析黑名单 ID 列表失败: {}", e.getMessage());
            return List.of();
        }
    }
}
